import edu.ucdavis.genomics.metabolomics.binbase.bci.cache.impl.SimpleCacheFactory
import grails.test.ControllerUnitTestCase
import types.Hit

class LookupControllerTests extends ControllerUnitTestCase {

  protected void setUp() {
    super.setUp()

    SimpleCacheFactory.newInstance().createCache().getCache().clear()

  }

  protected void tearDown() {
    super.tearDown()
    SimpleCacheFactory.newInstance().createCache().getCache().clear()

  }

  void testValidationOfParams() {

    LookupController.metaClass.getParams = {-> [hits: []] }

    LookupController controller = new LookupController()

    //should throw no excetption
    controller.lookup()
  }


  void testValidationOfParamsFailsNoParam() {

    LookupController.metaClass.getParams = {-> []}

    LookupController controller = new LookupController()

    try {

      //should throw no excetption
      controller.lookup()

      assertTrue(false)
    }
    catch (Error e) {
      println "success!"
    }
  }

  void testValidationOfParamsFailsWrongType() {

    LookupController.metaClass.getParams = {-> [hits: new Hit(type: Hit.KEGG, value: "C10000")] }

    LookupController controller = new LookupController()

    try {

      //should throw no excetption
      controller.lookup()

      assertTrue(false)
    }
    catch (Error e) {
      println "success!"
    }
  }

  void testLookupByPartialInchiKey() {
    LookupController.metaClass.getParams = {-> [inchiKey: "ATQXXRJEZULCTG"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupByPartialInchiKey().lookup

    println  "result.size() : ${result.size()}"
    assertTrue(result.size() == 1)

    for (def res: result) {
      assertTrue(res instanceof Compound)
    }
  }


  void testLookupByInchiKey() {
    LookupController.metaClass.getParams = {-> [inchiKey: "ATQXXRJEZULCTG-DLCFQVRISA-N"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupByInchiKey().lookup
    println  "result : ${result}"
    println  "result.inchi : ${result.inchi}"

    assertTrue(result instanceof Compound)

    assertTrue(result.inchi.trim() == "InChI=1S/C37H50N6O6/c1-9-22(4)31(43(7)8)35(47)41-30(21(2)3)34(46)42-32-36(48)40-28(18-24-19-38-27-13-11-10-12-26(24)27)33(45)39-20-29(44)23-14-16-25(17-15-23)49-37(32,5)6/h10-17,19,21-22,28,30-32,38H,9,18,20H2,1-8H3,(H,39,45)(H,40,48)(H,41,47)(H,42,46)/t22-,28-,30-,31-,32+/m0/s1")

  }


  void testLookupByInchi() {
    LookupController.metaClass.getParams = {-> [inchi: "InChI=1S/C7H11N3O2/c1-10-3-5(9-4-10)2-6(8)7(11)12/h3-4,6H,2,8H2,1H3,(H,11,12)/t6-/m0/s1"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupByInchi().lookup

    print "result :: ${result}"

    assertTrue(result instanceof Compound)

    assertTrue(result.inchi == "InChI=1S/C7H11N3O2/c1-10-3-5(9-4-10)2-6(8)7(11)12/h3-4,6H,2,8H2,1H3,(H,11,12)/t6-/m0/s1")

  }


  void testLookupByCompoundId() {
    LookupController.metaClass.getParams = {-> [compoundId: "931418"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupByCompoundId().lookup

    println "testLookupByCompoundId :: result :: ${result}"

    assertTrue(result instanceof Compound)
    println "testLookupByCompoundId :: result.inchi :: ${result.inchi}"
    
    assertTrue(result.inchi.trim() == "InChI=1S/C33H36N4O4/c1-36(2)28(22-24-10-5-3-6-11-24)32(39)35-29-30(25-12-7-4-8-13-25)41-26-17-15-23(16-18-26)19-20-34-31(38)27-14-9-21-37(27)33(29)40/h3-8,10-13,15-20,27-30H,9,14,21-22H2,1-2H3,(H,34,38)(H,35,39)/b20-19-/t27-,28-,29-,30+/m0/s1")

  }


  void testLookupByKegg() {
    LookupController.metaClass.getParams = {-> [kegg: "C10000"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()


    def result = controller.lookupByKegg().lookup

    println "result :: ${result}"

    assertTrue(result.size() == 1)

    for (def res: result) {
      assertTrue(res instanceof Compound)
      assertTrue(res.id == 931418)
    }
  }

  void testLookupByCas() {
    LookupController.metaClass.getParams = {-> [cas: "553-97-9"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()


    def result = controller.lookupByCas().lookup

    println result
    assertTrue(result.size() == 1)

    for (def res: result) {
      assertTrue(res instanceof Compound)
      assertTrue(res.id == 308738)
    }

  }

  void testLookupByCID() {
    LookupController.metaClass.getParams = {-> [cid: "1"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupByCID().lookup
    //println result
    assertTrue(result.size() == 1)

    for (def res: result) {
      assertTrue(res instanceof Compound)
      assertTrue(res.id == 931715)
    }

  }

  void testLookupBySID() {
    LookupController.metaClass.getParams = {-> [sid: "74380251"] }
    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupBySID().lookup
    println result 
    assertTrue(result.size() == 1)

    for (def res: result) {
      assertTrue(res instanceof Compound)
      assertTrue(res.id == 931396)
    }
  }


  void testLookupBySmile() {
    LookupController.metaClass.getParams = {-> [smile: "CC(CN)O"] }

    LookupController controller = new LookupController()
    controller.lookupService = new LookupService()

    def result = controller.lookupBySmile()

    for (def res: result.lookup) {
      assertTrue(res instanceof Compound)
    }
    
    println "result.lookup.size() :: ${result.lookup.size()}"

    assertTrue(result.lookup.size() == 2)
  }



}
